package com.lantaiyuan.ebus.util;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.IosNotification.Builder;
import cn.jpush.api.push.model.notification.Notification;

/**
 * 描述:消息推送帮助类 作者:温海金 最后更改时间:下午3:47:38
 */
public class JpushHelper {

	private static String APP_KEY = "71630fa6f6905ac698fcadff";
	private static String MASTER_SECRET = "eeb9831e7373ee90487530e0";
	private static Logger logger = Logger.getLogger(JpushHelper.class);
	private static String IP_ADDRESS = null;
	private static String WEB_NAME = "BMTA";
	private static JPushClient jpushClient = null;
	private static HashMap<String, String> extras = new HashMap<String, String>();

	private static String getLocalIpAddress() {
		String ipAddress = null;
		Enumeration allNetInterfaces;
		try {
			allNetInterfaces = NetworkInterface.getNetworkInterfaces();
			InetAddress ip = null;
			while (allNetInterfaces.hasMoreElements()) {
				NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
				Enumeration addresses = netInterface.getInetAddresses();
				while (addresses.hasMoreElements()) {
					ip = (InetAddress) addresses.nextElement();
					if (ip != null && ip instanceof Inet4Address) {
						ipAddress = ip.getHostAddress();
						break;
					}
				}
			}
			return ipAddress;
		} catch (SocketException e) {
			e.printStackTrace();
			return ipAddress;
		}
	}

	static {
		IP_ADDRESS = getLocalIpAddress();
		if(IP_ADDRESS!=null) {
			extras.put("ip", IP_ADDRESS);
		}
		extras.put("webName", WEB_NAME);
	}

	public static JPushClient getJPushClient() {
		if (jpushClient == null) {
			synchronized (JpushHelper.class) {
				if (jpushClient == null) {
					ClientConfig instance = ClientConfig.getInstance();
					instance.setApnsProduction(true);
					jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, instance);
				}
			}
		}
		return jpushClient;
	}

	/**
	 * 功能描述:向所有用户发送消息推送 作者:温海金 最后更改时间 : 2017年2月20日 下午3:48:12
	 */
	private static PushPayload buildPushObject_all_all_alert(String pushMsg) {
		return PushPayload.alertAll(pushMsg);
	}

	/**
	 * 功能描述:向所有用户进行消息推送 参数: pushContent表示要推送的具体内容 作者:温海金 最后更改时间 : 2017年2月20日
	 * 下午3:48:12
	 */
	public static void pushAll(String pushMsg) {
		PushPayload payload = buildPushObject_all_all_alert(pushMsg);
		try {
			PushResult result = getJPushClient().sendPush(payload);
			logger.info("成功发送消息推送 - " + result);

		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);

		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * 功能描述:根据registrationId向用户发送消息 参数: pushContent表示要推送的具体内容 作者:温海金 最后更改时间 :
	 * 2017年2月20日 下午3:48:12
	 */
	public static void sendMessageWithRegistrationID(String title, String msgContent, String registrationID) {
		try {
			getJPushClient().sendMessageWithRegistrationID(title, msgContent, registrationID);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * 构建推送对象:所有平台，推送目标是别名为alias，通知内容为 pushMsg。 作者:温海金 最后更改时间 : 2017年2月20日
	 * 下午4:06:00
	 */
	public static PushPayload buildPushObject_all_alias_alert(String alias, String pushMsg) {
		return PushPayload.newBuilder().setPlatform(Platform.all()).setAudience(Audience.alias(alias))
				.setNotification(Notification.alert(pushMsg)).build();
	}

	/**
	 * 构建推送对象:平台是 Android，目标是 tag 为 taget 的设备，内容是 Android 通知 pushMsg，并且标题为
	 * title。 作者:温海金 最后更改时间 : 2017年2月20日 下午4:12:04
	 */
	public static PushPayload buildPushObject_android_tag_alertWithTitle(String taget, String pushMsg, String title) {
		return PushPayload.newBuilder().setPlatform(Platform.android()).setAudience(Audience.tag(taget))
				.setNotification(Notification.android(pushMsg, title, null)).build();
	}

	/**
	 * 构建推送对象：平台是 iOS，推送目标是 "tag1", "tag_all" 的交集， 推送内容同时包括通知与消息 - 通知信息是
	 * notifyAlert，角标数字为 5， 通知声音为 "happy"，并且附加字段 from = "JPush"； 消息内容是
	 * msgContent。 通知是 APNs 推送通道的，消息是 JPush 应用内消息通道的。 APNs
	 * 的推送环境是“生产”（如果不显式设置的话，Library 会默认指定为开发） 作者:温海金 最后更改时间 : 2017年2月20日
	 * 下午4:15:27
	 */
	public static PushPayload buildPushObject_ios_tagAnd_alertWithExtrasAndMessage(String tag1, String tag_all,
			String notifyAlert, String happy, String msgContent) {
		return PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.tag_and(tag1, tag_all))
				.setNotification(Notification.newBuilder()
						.addPlatformNotification(IosNotification.newBuilder().setAlert(notifyAlert).setBadge(5)
								.setSound(happy).addExtra("from", "JPush").build())
						.build())
				.setMessage(Message.content(msgContent))
				.setOptions(Options.newBuilder().setApnsProduction(true).build()).build();
	}

	/**
	 * 构建推送对象：平台是 Andorid 与 iOS，推送目标是 （"tag1" 与 "tag2" 的并集）交（"alias1" 与 "alias2"
	 * 的并集）， 推送内容是 - 内容为 msgContent 的消息，并且附加字段 from = JPush。 作者:温海金 最后更改时间 :
	 * 2017年2月20日 下午4:20:46
	 */
	public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras(String tag1, String tag2,
			String alias1, String alias2, String msgContent) {
		return PushPayload.newBuilder().setPlatform(Platform.android_ios())
				.setAudience(Audience.newBuilder().addAudienceTarget(AudienceTarget.tag(tag1, tag2))
						.addAudienceTarget(AudienceTarget.alias(alias1, alias2)).build())
				.setMessage(Message.newBuilder().setMsgContent(msgContent).addExtra("from", "JPush").build()).build();
	}

	/**
	 * 功能描述:根据registrationId向用户发送通知 参数: pushContent表示要推送的具体内容 作者:温海金 最后更改时间 :
	 * 2017年2月20日 下午3:48:12
	 */
	public static void sendNotificationWithRegistrationID(String title, String msgContent, String registrationID) {
		try {
			getJPushClient().sendIosNotificationWithRegistrationID(msgContent, null, registrationID);
			getJPushClient().sendAndroidNotificationWithRegistrationID(title, msgContent, null, registrationID);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * <p>
	 * Title: 向单个用户发送消息
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 */
	public static void sendAndroid(String title, String msgContent, String registrationID) {
		try {
			getJPushClient().sendAndroidMessageWithRegistrationID(title, msgContent, registrationID);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * <p>
	 * Title: 向用户组发送消息
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 */
	public static void sendAndroid4Group(String title, String msgContent, List<String> regIds) {
		regIds.forEach(regId -> {
			sendAndroid(title, msgContent, regId);
		});
	}

	/**
	 * <p>
	 * Title: 向单个用户发送消息
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 */
	public static void sendIos(String title, String msgContent, String registrationID) {
		try {
			getJPushClient().sendIosNotificationWithRegistrationID(msgContent, null, registrationID);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * <p>
	 * Title: 向用户组发送消息
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 */
	public static void sendIos4Group(String title, String msgContent, List<String> regIds) {
		regIds.forEach(regId -> {
			sendIos(title, msgContent, regId);
		});
	}

	/**
	 * 
	 * <p>
	 * Title: sendMessageAndroidWithExtra
	 * </p>
	 * <p>
	 * Description: 给安卓用户发送自定义消息
	 * </p>
	 * 
	 * @param title
	 * @param msgContent
	 * @param registrationID
	 */
	public static void sendMessageAndroidWithExtra(String title, String msgContent, String registrationID) {
		try {
			logger.warn("android推送前:title:" + title + ",msgContent:" + msgContent + ",registrationID:" + registrationID);
			PushResult pushResult = getJPushClient().sendPush(getAndroidMessagePushPayload(msgContent, registrationID, extras));
			logger.warn("android推送后极光返回结果:" + pushResult.toString());
			logger.warn("给安卓用户发送自定义消息:regId:" + registrationID + "-ip地址:" + IP_ADDRESS + "-应用名称:" + WEB_NAME);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	/**
	 * 
	 * <p>
	 * Title: sendMessageAndroidWithExtra
	 * </p>
	 * <p>
	 * Description:给IOS用户发送通知
	 * </p>
	 * 
	 * @param title
	 * @param msgContent
	 * @param registrationID
	 */
	public static void sendNotifyIOSWithExtra(String title, String msgContent, String registrationID) {
		try {
			logger.warn("ios推送前:title:" + title + ",msgContent:" + msgContent + ",registrationID:" + registrationID);
			PushResult pushResult = getJPushClient().sendPush(JpushHelper.buildPushObject4IOSWithExtrasAndMessage(msgContent, registrationID, extras));
			logger.warn("ios推送后极光返回结果:" + pushResult.toString());
			logger.warn("给ios用户发送通知:regId:" + registrationID + "-ip地址:" + IP_ADDRESS + "-应用名称:" + WEB_NAME);
		} catch (APIConnectionException e) {
			logger.error("连接异常，请稍后再试", e);
		} catch (APIRequestException e) {
			logger.error("消息推送出错", e);
			logger.info("HTTP状态码: " + e.getStatus());
			logger.info("错误代码: " + e.getErrorCode());
			logger.info("报错信息: " + e.getErrorMessage());
		}
	}

	private static PushPayload getAndroidMessagePushPayload(String msgContent, String registrationId,
			Map<String, String> extras) {
		cn.jpush.api.push.model.Message.Builder builder = cn.jpush.api.push.model.Message.newBuilder();
		return PushPayload.newBuilder().setPlatform(Platform.android())
				.setAudience(Audience.registrationId(registrationId))
				.setMessage(builder.addExtras(extras).setMsgContent(msgContent).build()).build();
	}

	private static PushPayload buildPushObject4IOSWithExtrasAndMessage(String msgContent, String registrationId,
			Map<String, String> extras) {
		Builder iosBuilder = IosNotification.newBuilder().setAlert(msgContent).setSound("default");
		Set<Entry<String, String>> entrySet = extras.entrySet();
		entrySet.forEach(mapEntry -> {
			iosBuilder.addExtra(mapEntry.getKey(), mapEntry.getValue());
		});
		IosNotification iosBuild = iosBuilder.build();
		return PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.registrationId(registrationId))

				.setNotification(Notification.newBuilder().addPlatformNotification(iosBuild).build()).build();
	}
}
